﻿/**************************************************************
*作者：Leon
*创建时间：2022/5/4 14:34:47
**************************************************************/
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace UnitTestingDemo
{
    public class UnitTestingDemo
    {
        [Fact]
        public void SimpleTest()
        {
            var moq = new Mock<IDataBaseContext<MyDto>>();
            MyBll bll = new MyBll(moq.Object);
            var result = bll.GetADto(null);
            Assert.Null(result);
        }
        [Fact]
        public void ShouldReturn_A_Dto_If_QueryBy_Id_With_Valid_Parameter()
        {
            var moq = new Mock<IDataBaseContext<MyDto>>();
            moq.Setup(a => a.GetElementById(It.IsAny<string>())).Returns(new MyDto());
            MyBll bll = new MyBll(moq.Object);
            var dto = bll.GetADto("afakeid");

            Assert.NotNull(dto);
        }

        [Fact]
        public void ShouldReturn_A_Collection_Of_Dtos()
        {
            var moq = new Mock<IDataBaseContext<MyDto>>();
            moq.Setup(a => a.GetAll()).Returns(new List<MyDto>
            {
                new MyDto{Name="baidu",Age=15},
                new MyDto{Name="sto",Age=32},
                new MyDto{Name="zto",Age=24},
                new MyDto{Name="yto",Age=12}
            });
            MyBll bll = new MyBll(moq.Object);
            var dtos = bll.GetAllDtos().ToList();

            Assert.NotEmpty(dtos);
        }
        [Fact]
        public void ShouldReturn_True_If_Id_Is_9527()
        {
            var moq = new Mock<IDataBaseContext<MyDto>>();
            moq.Setup(a => a.GetElementById(It.Is<string>(t => t.Trim() == "9527"))).Returns(new MyDto { Name = "sto", Age = 24 });
            MyBll bll = new MyBll(moq.Object);
            bool isVip = bll.IsVip("9527");
            Assert.True(isVip);
        }
        [Fact]
        public void MockOf_Test()
        {
            var obj = Mock.Of<IDataBaseContext<MyDto>>(a => a.GetAll()==new List<MyDto>() { new MyDto() }
                                                           &&a.GetElementById(It.IsAny<string>())==new MyDto()
                                                           &&a.GetElementsByName(It.IsAny<string>())==new MyDto[3]);
            var all = obj.GetAll();
            var one = obj.GetElementById("s");
            var some = obj.GetElementsByName("somename");

            Assert.Single(all);
            Assert.NotNull(one);
            Assert.Equal(3, some.Count());
        }
    }

    public class MyDto
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public interface IDataBaseContext<out T> where T : new()
    {
        T GetElementById(string id);
        IEnumerable<T> GetAll();
        IEnumerable<T> GetElementsByName(string name);
        IEnumerable<T> GetPageElementsByName(string name, int startPage = 0, int pageSize = 20);
        IEnumerable<T> GetElementsByDate(DateTime? startDate, DateTime? endDate);
    }

    public class MyBll
    {
        private readonly IDataBaseContext<MyDto> _dataBaseContext;

        public MyBll(IDataBaseContext<MyDto> dataBaseContext)
        {
            _dataBaseContext = dataBaseContext;
        }

        public MyDto GetADto(string id)
        {
            if (string.IsNullOrWhiteSpace(id)) return null;
            return _dataBaseContext.GetElementById(id);
        }

        public IEnumerable<MyDto> GetAllDtos()
        {
            var all = _dataBaseContext.GetAll().ToList();
            if (!all.Any()) return Enumerable.Empty<MyDto>();
            //一系列逻辑...
            var filteredDtos = all.Where(a => a.Age > 20);
            var orderDtos = filteredDtos.OrderBy(a => a.Name);
            return orderDtos;
        }

        public bool IsVip(string id)
        {
            if (string.IsNullOrWhiteSpace(id)) return false;
            var dto = _dataBaseContext.GetElementById(id);
            if (dto?.Name?.Contains("sto")==true) return true;
            return false;
        }

    }

}
